Skip to content

[Fleet] Extend OTel exporter configuration#259308

Merged
criamico merged 43 commits intoelastic:mainfrom
criamico:255019_extend_otel_exporter_config
Apr 8, 2026
Merged

[Fleet] Extend OTel exporter configuration#259308
criamico merged 43 commits intoelastic:mainfrom
criamico:255019_extend_otel_exporter_config

Conversation

@criamico
Copy link
Copy Markdown
Member

@criamico criamico commented Mar 24, 2026

Closes #255019

Summary

Extend OTel exporter configuration: The existing exporter generation only mapped hosts from an Elasticsearch output. All other config (SSL, proxy, TLS, custom params) was ignored.

  • Adds a beatsauth/<outputID> extension to every OTel policy that uses an ES output. This extension carries SSL fields and proxy settings from the Fleet output config.
  • Merges the new otel_exporter_config_yaml field into the exporter config.
  • preset is intentionally ignored for now (the exporter uses its own defaults).
  • Adds an "OpenTelemetry Exporter" panel (ES outputs only) with an "Advanced YAML Configuration" editor. Content is saved as otel_exporter_config_yaml and merged into the OTel exporter at policy generation time.

Testing

  1. Create an Elasticsearch output with SSL settings in Settings → Outputs → Add output:
Type: Elasticsearch
Hosts: https://your-es-host:9200
CA Trusted Fingerprint: any hex string, e.g. abc123def456
(Optionally add SSL certificate/key under Advanced)
  1. Create an agent policy with an OTel integration in Agent Policies → Create policy
    Assign the output you just created to the policy
    Add an OTel-based integration - I tested with filelog_otel-0.2.0 but any otel input integration (not content only) will do
  2. Verify the generated agent policy. In the response, look for the top-level extensions, exporters, and service keys. You should see:
extensions:
  beatsauth/<output-id>:          # e.g. beatsauth/default or beatsauth/my-output-id
    ssl:
      ca_trusted_fingerprint: abc123def456
      # ... any other SSL fields you configured

exporters:
  elasticsearch/<output-id>:
    endpoints:
      - https://your-es-host:9200
    auth:
      authenticator: beatsauth/<output-id>   # ← new field

service:
  extensions:
    - beatsauth/<output-id>                  # ← registered in service
  1. Test with a proxy - Settings → Proxies → Add proxy → set a URL
    Edit your output and assign the proxy. Re-fetch the full agent policy — the beatsauth extension should now also include:
beatsauth/<output-id>:
  proxy_url: http://localhost:3128
  ssl:
    ca_trusted_fingerprint: abc123def456
  1. Test with a yaml custom parameter - add a yaml parameter under Advanced YAML Configuration
    This parameter should now be visible in the generated policy
Screenshots Screenshot 2026-03-25 at 11 24 51 Screenshot 2026-03-25 at 16 22 49 Screenshot 2026-03-25 at 16 23 30

Checklist

Check the PR satisfies following conditions.

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.

@criamico criamico changed the title 255019 extend otel exporter config [Fleet] Extend OTel exporter configuration Mar 25, 2026
@criamico
Copy link
Copy Markdown
Member Author

@elasticmachine merge upstream

@criamico criamico self-assigned this Mar 25, 2026
@criamico criamico added Team:Fleet Team label for Observability Data Collection Fleet team v9.4.0 release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting labels Mar 25, 2026
@criamico
Copy link
Copy Markdown
Member Author

Example of policy generated after this change:

id: e60a406d-7f8e-4afc-bfc6-b399f55090f9
revision: 6
outputs:
  a32c37a7-900b-4440-8c06-a6514e095098:
    type: elasticsearch
    hosts:
      - http://test-host:80
    secrets:
      ssl:
        key:
          id: 6ZAvH50BFEDfHFivzCrf
    ssl:
      certificate: certificate
      certificate_authorities: []
      key: '-----BEGIN PRIVATE KEY-----LEAK_ME_PROXY_KEY-----END PRIVATE KEY-----'
    proxy_url: https://proxy.internal.example:8443
    proxy_headers:
      Authorization: Bearer PROXY_SECRET
    preset: balanced
fleet:
  hosts:
    - https://host.docker.internal:8220
output_permissions:
  a32c37a7-900b-4440-8c06-a6514e095098:
    _elastic_agent_monitoring:
      indices:
        - names:
            - logs-elastic_agent.apm_server-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.apm_server-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.auditbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.auditbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.cloud_defend-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.cloudbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.cloudbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.elastic_agent-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.endpoint_security-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.endpoint_security-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.filebeat_input-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.filebeat_input-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.filebeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.filebeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.fleet_server-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.fleet_server-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.heartbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.heartbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.metricbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.metricbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.osquerybeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.osquerybeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.packetbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - metrics-elastic_agent.packetbeat-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.pf_elastic_collector-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.pf_elastic_symbolizer-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.pf_host_agent-default
          privileges:
            - auto_configure
            - create_doc
        - names:
            - logs-elastic_agent.status_change-default
          privileges:
            - auto_configure
            - create_doc
    _elastic_agent_checks:
      cluster:
        - monitor
    1a458fca-7c0f-4cf0-bd2c-291ff8844f1c:
      indices:
        - names:
            - logs-*-*
          privileges:
            - auto_configure
            - create_doc
agent:
  download:
    sourceURI: https://artifacts.elastic.co/downloads/
    ssl:
      key: '-----BEGIN PRIVATE KEY-----LEAK_ME_PROXY_KEY-----END PRIVATE KEY-----'
    proxy_url: https://proxy.internal.example:8443
    proxy_headers:
      Authorization: Bearer PROXY_SECRET
  monitoring:
    enabled: true
    use_output: a32c37a7-900b-4440-8c06-a6514e095098
    logs: true
    metrics: true
    traces: true
    namespace: default
  features: {}
  protection:
    enabled: false
    uninstall_token_hash: ***
    signing_key: ***
inputs: []
signed:
 ...
receivers:
  filelog/otelcol-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c-otelcol-filelog_otel-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c:
    include:
      - aaaa
    start_at: end
    max_concurrent_files: 1024
    include_file_name: true
    include_file_path: false
    include_file_name_resolved: false
    include_file_path_resolved: false
    include_file_owner_name: false
    include_file_owner_group_name: false
    include_file_record_number: false
    include_file_record_offset: false
    encoding: utf-8
    preserve_leading_whitespaces: false
    preserve_trailing_whitespaces: false
    fingerprint_size: 1kb
    initial_buffer_size: 16KiB
    max_log_size: 1MiB
    poll_interval: 200ms
    force_flush_period: 500ms
service:
  pipelines:
    logs/otelcol-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c-otelcol-filelog_otel-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c:
      receivers:
        - >-
          filelog/otelcol-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c-otelcol-filelog_otel-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c
      processors:
        - >-
          transform/otelcol-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c-otelcol-filelog_otel-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c-routing
      exporters:
        - forward
    logs:
      receivers:
        - forward
      exporters:
        - elasticsearch/a32c37a7-900b-4440-8c06-a6514e095098
  extensions:
    - beatsauth/a32c37a7-900b-4440-8c06-a6514e095098
processors:
  transform/otelcol-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c-otelcol-filelog_otel-filelogreceiver-1a458fca-7c0f-4cf0-bd2c-291ff8844f1c-routing:
    log_statements:
      - context: log
        statements:
          - set(attributes["data_stream.type"], "logs")
          - set(attributes["data_stream.dataset"], "filelogreceiver")
          - set(attributes["data_stream.namespace"], "default")
connectors:
  forward: {}
extensions:
  beatsauth/a32c37a7-900b-4440-8c06-a6514e095098:
    ssl:
      certificate: certificate
    proxy_url: https://proxy.internal.example:8443
    proxy_headers:
      Authorization: Bearer PROXY_SECRET
exporters:
  elasticsearch/a32c37a7-900b-4440-8c06-a6514e095098:
    flush_interval: 10s
    endpoints:
      - http://test-host:80
    auth:
      authenticator: beatsauth/a32c37a7-900b-4440-8c06-a6514e095098
secret_references:
  - id: 6ZAvH50BFEDfHFivzCrf
namespaces:
  - default

@criamico criamico marked this pull request as ready for review March 25, 2026 16:07
@criamico criamico requested review from a team as code owners March 25, 2026 16:07
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/fleet (Team:Fleet)

Comment thread x-pack/platform/plugins/shared/fleet/server/saved_objects/index.ts
if (output.ssl?.certificate_authorities?.length)
ssl.certificate_authorities = output.ssl.certificate_authorities;
if (output.ssl?.certificate) ssl.certificate = output.ssl.certificate;
if (output.ssl?.key) ssl.key = output.ssl.key;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we handle secrets here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, I missed it

[`elasticsearch/${outputID}`]: {
endpoints: dataOutput.hosts,
extensions: {
[beatsauthID]: buildBeatsauthConfig(dataOutput, proxy),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when buildBeatsauthConfig returns {}, should we still add beatsauth to extensions and exporters?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are still adding a beatsuath extension and exporter if the config is empty

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4451e00

@criamico
Copy link
Copy Markdown
Member Author

@elasticmachine merge upstream

@elastic-vault-github-plugin-prod elastic-vault-github-plugin-prod Bot requested a review from a team as a code owner March 26, 2026 16:36
Copy link
Copy Markdown
Contributor

@juliaElastic juliaElastic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@criamico
Copy link
Copy Markdown
Member Author

criamico commented Apr 2, 2026

@elasticmachine merge upstream

@criamico
Copy link
Copy Markdown
Member Author

criamico commented Apr 2, 2026

@jloleysens there is a failure that keeps happening in the check API contract check: https://buildkite.com/elastic/kibana-pull-request/builds/421398#019d4e7c-00ec-48ad-b6bb-dd0b2f0ad693

I think it's not regenerating the OAS doc, how can I fix it?

Comment thread x-pack/platform/plugins/shared/fleet/server/saved_objects/index.ts
@kibanamachine
Copy link
Copy Markdown
Contributor

API Contract Breaking Changes — Terraform Provider Impact

cc @elastic/fleet

The following breaking change(s) affect APIs consumed by the Elastic Terraform Provider.

Endpoint Terraform Resource Reason Owners
/api/fleet/outputs/{outputId} PUT elasticstack_fleet_output removed 'subschema #1, subschema #2, subschema #3, subschema #4' from the request body 'anyOf' list @elastic/fleet

What to do

  1. Fix the breaking change if it was unintentional.
  2. If intentional, add an approved entry to packages/kbn-api-contracts/allowlist.json and coordinate with @elastic/terraform-provider.

See the @kbn/api-contracts README for details on the allowlist schema and workflow.

@criamico
Copy link
Copy Markdown
Member Author

criamico commented Apr 8, 2026

@elasticmachine merge upstream

@criamico
Copy link
Copy Markdown
Member Author

criamico commented Apr 8, 2026

@elasticmachine merge upstream

@elasticmachine
Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Fleet Cypress Tests #1 / View agents list Bulk actions should navigate to Maintenance and diagnostics submenu
  • [job] [logs] Fleet Cypress Tests #1 / View agents list Bulk actions should navigate to Security and removal submenu and show unenroll option
  • [job] [logs] Fleet Cypress Tests #1 / View agents list Bulk actions should show hierarchical menu with submenus

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
fleet 2.3MB 2.3MB +1.6KB

History

cc @criamico

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Fleet Team label for Observability Data Collection Fleet team v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fleet] Completely translate Elasticsearch output configurations into Elasticsearch exporter configurations

9 participants